using System;
using System.Collections.Generic;
using System.Text;
using EnvDTE80;
using EnvDTE;

namespace Koda.Model
{
    public class MemberComparer : IComparer<Member>
    {
        private MemberInfoCollection memberInfoOrder;

        public MemberComparer()
        {
            this.memberInfoOrder = new MemberInfoCollection();
            this.memberInfoOrder.Add(MemberType.Constant, MemberAccess.Public, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Variable, MemberAccess.Public, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Constant, MemberAccess.Private, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Other, MemberAccess.Private, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Variable, MemberAccess.Private, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Variable, MemberAccess.Public, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Variable, MemberAccess.Private, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Variable, MemberAccess.Other, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Constructor, MemberAccess.Public, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Constructor, MemberAccess.Private, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Constructor, MemberAccess.Public, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Constructor, MemberAccess.Private, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Delegate, MemberAccess.Public, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Delegate, MemberAccess.Private, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Delegate, MemberAccess.Public, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Delegate, MemberAccess.Private, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Event, MemberAccess.Public, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Event, MemberAccess.Private, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Event, MemberAccess.Public, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Event, MemberAccess.Private, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Enum, MemberAccess.Public, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Enum, MemberAccess.Private, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Property, MemberAccess.Public, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Property, MemberAccess.Public, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Property, MemberAccess.Other, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Property, MemberAccess.Private, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Property, MemberAccess.Other, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Property, MemberAccess.Protected, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Property, MemberAccess.Private, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Function, MemberAccess.Public, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Function, MemberAccess.Private, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Function, MemberAccess.Other, MemberScope.Static);
            this.memberInfoOrder.Add(MemberType.Function, MemberAccess.Public, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Function, MemberAccess.Other, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Function, MemberAccess.Protected, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Function, MemberAccess.Private, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Struct, MemberAccess.Public, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Struct, MemberAccess.Private, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Class, MemberAccess.Public, MemberScope.Instance);
            this.memberInfoOrder.Add(MemberType.Class, MemberAccess.Private, MemberScope.Instance);

        }

        public int Compare(Member x, Member y)
        {
            if (x.Info.Equals(y.Info))
            {
                return x.Name.CompareTo(y.Name);
            }
            else
            {
                if (this.memberInfoOrder.IndexOf(x.Info) > this.memberInfoOrder.IndexOf(y.Info))
                    return 1;
                return -1;                  
            }
        }


    }
}